package com.greenold.finance.service.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.Date;

import com.greenold.commen.domain.Dto.ElderBillsDto;
import com.greenold.commen.domain.Elder;
import com.greenold.commen.mapper.ElderMapper;
import com.greenold.common.IBillServiceQuartz;
import com.greenold.finance.dto.BillDto;
import com.greenold.finance.vo.ElderBillVo;
import com.greenold.system.domain.WxChatCustomer;
import com.greenold.system.mapper.WxChatCustomerMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.greenold.finance.mapper.BillMapper;
import com.greenold.finance.domain.Bill;
import com.greenold.finance.service.IBillService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 入账列表Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-10-13
 */
@Service
public class BillServiceImpl implements IBillService, IBillServiceQuartz
{
    @Autowired
    private BillMapper billMapper;
    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private WxChatCustomerMapper wxChatCustomerMapper;
    /**
     * 查询入账列表
     * 
     * @param id 入账列表主键
     * @return 入账列表
     */
    @Override
    public Bill selectBillById(String id)
    {
        return billMapper.selectBillById(id);
    }

    /**
     * 查询入账列表列表
     * 
     * @param bill 入账列表
     * @return 入账列表
     */
    @Override
    public List<Bill> selectBillList(Bill bill)
    {
        return billMapper.selectBillList(bill);
    }

    /**
     * 新增入账列表
     * 
     * @param bill 入账列表
     * @return 结果
     */
    @Override
    public int insertBill(Bill bill)
    {
        return billMapper.insertBill(bill);
    }

    /**
     * 修改入账列表
     * 
     * @param bill 入账列表
     * @return 结果
     */
    @Override
    public int updateBill(Bill bill)
    {
        return billMapper.updateBill(bill);
    }

    /**
     * 批量删除入账列表
     * 
     * @param ids 需要删除的入账列表主键
     * @return 结果
     */
    @Override
    public int deleteBillByIds(String[] ids)
    {
        return billMapper.deleteBillByIds(ids);
    }

    /**
     * 删除入账列表信息
     * 
     * @param id 入账列表主键
     * @return 结果
     */
    @Override
    public int deleteBillById(String id)
    {
        return billMapper.deleteBillById(id);
    }
    @Override
    public BillDto selectBillByBillNo(String billNo)
    {
        return billMapper.selectBillByBillNo(billNo);
    }
    @Override
    public List<Bill> selectBillByElderId(String elderId){
        return billMapper.selectBillByElderId(elderId);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void autoGenerateMonthlyBills() {
        // ======= 获取上个月的账单周期 =======
        LocalDate now = LocalDate.now();
        LocalDate billStart = now.minusMonths(1).withDayOfMonth(1);  // 上月1号
        LocalDate billEnd = now.minusMonths(1).withDayOfMonth(now.minusMonths(1).lengthOfMonth()); // 上月最后一天
        int totalDays = billEnd.getDayOfMonth(); // 共计天数

        String billMonth = billStart.format(DateTimeFormatter.ofPattern("yyyy-MM"));

        // 查询所有已入住老人
        List<ElderBillVo> elderBillVos = elderMapper.selectElderBillVo();

        if (elderBillVos == null || elderBillVos.isEmpty()) {
            System.out.println("未查询到已入住老人信息，跳过账单生成");
            return;
        }
        for (ElderBillVo ebv : elderBillVos) {
            if (ebv == null || ebv.getElderId() == null) {
                System.out.println("ElderBillVo为空或elderId为空，跳过该记录");
                continue;
            }

            Bill bill = new Bill();
            // 基础字段
            bill.setBillNo("ZD" + UUID.randomUUID().toString().replace("-", "").substring(0, 10));
            bill.setBillType("0"); // 月度账单
            bill.setBillMonth(billMonth);
            bill.setElderId(ebv.getElderId());
            // ======= 各项费用 =======
            BigDecimal careFee = BigDecimal.valueOf(ebv.getCareFee() == null ? 0.0 : ebv.getCareFee());
            BigDecimal bedFee = BigDecimal.valueOf(ebv.getBedFee() == null ? 0.0 : ebv.getBedFee());
            BigDecimal otherFee = BigDecimal.ZERO;
            BigDecimal medicalPay = BigDecimal.ZERO;
            BigDecimal subsidy = BigDecimal.ZERO;
            BigDecimal deposit = BigDecimal.valueOf(1000.00);
            BigDecimal prepaid = BigDecimal.valueOf(1000.00);

            // ======= 计算逻辑 =======
            // 每月应付
            BigDecimal monthlyPayable = careFee.add(bedFee).add(otherFee)
                    .subtract(medicalPay).subtract(subsidy);

            // 本期应付 = 全月算
            BigDecimal currentPayable = monthlyPayable;

            // 账单金额 = 本期应付 + 押金
            BigDecimal billAmount = currentPayable.add(deposit);

            // 应付金额 = 账单金额 - 预缴款
            BigDecimal payableAmount = billAmount.subtract(prepaid);

            // ======= 设置账单信息 =======
            bill.setBillAmount(billAmount);
            bill.setPayableAmount(payableAmount);
            bill.setPrepaidAmount(prepaid);
            bill.setDepositAmount(deposit);
            bill.setCurrentPayable(currentPayable);
            bill.setBillStatus("0");

            // ======= 账单周期 =======
            bill.setBillStartTime(java.sql.Date.valueOf(billStart));
            bill.setBillEndTime(java.sql.Date.valueOf(billEnd));
            bill.setTotalDays(String.valueOf(totalDays));
            // 支付截止时间 = 账单开始时间 + 6天
            LocalDate paymentDeadline = billStart.plusDays(6);
            bill.setPaymentDeadline(java.sql.Date.valueOf(paymentDeadline));

            bill.setCreatedAt(new Date());
            bill.setUpdatedAt(new Date());
            bill.setCareLevelName(ebv.getCareLevelName());
            bill.setRoomTypeName(ebv.getRoomTypeName());

            // 插入账单
            billMapper.insertBill(bill);
        }
    }
    @Override
    public List<ElderBillsDto> getBillListById(String userId){
        WxChatCustomer wxChatCustomer = wxChatCustomerMapper.selectWxChatCustomerByUserId(userId);
        if(wxChatCustomer == null)
        {
            return null;
        }
        Long idLong = (Long) wxChatCustomer.getId();
        Integer idInteger = idLong.intValue();
        List<Integer> ElderIds = wxChatCustomerMapper.selectElderIdsById(idInteger);
        List<ElderBillsDto> ElderBillsDtos = new ArrayList<>();
        for(Integer ElderId:ElderIds)
        {
            Elder elder = elderMapper.selectElderById(ElderId.toString());
            if(elder == null)
            {
                continue;
            }
            List<Bill> bills = billMapper.selectBillByElderId(ElderId.toString());
            ElderBillsDto elderBillsDto = new ElderBillsDto();
            elderBillsDto.setId(elder.getId());
            elderBillsDto.setName(elder.getName());
            elderBillsDto.setIdCard(elder.getIdCard());
            elderBillsDto.setPhoto(elder.getPhoto());
            elderBillsDto.setGender(elder.getGender());
            elderBillsDto.setBirthDate(elder.getBirthDate());
            elderBillsDto.setAge(elder.getAge());
            elderBillsDto.setMobile(elder.getMobile());
            elderBillsDto.setAddress(elder.getAddress());
            elderBillsDto.setEthnicity(elder.getEthnicity());
            elderBillsDto.setPolitical(elder.getPolitical());
            elderBillsDto.setReligion(elder.getReligion());
            elderBillsDto.setMaritalStatus(elder.getMaritalStatus());
            elderBillsDto.setEducation(elder.getEducation());
            elderBillsDto.setIncomeSource(elder.getIncomeSource());
            elderBillsDto.setHobbies(elder.getHobbies());
            elderBillsDto.setMedicalSecurity(elder.getMedicalSecurity());
            elderBillsDto.setMedicalCardNo(elder.getMedicalCardNo());
            elderBillsDto.setFamilyMembers(elder.getFamilyMembers());
            elderBillsDto.setIdCardFront(elder.getIdCardFront());
            elderBillsDto.setIdCardBack(elder.getIdCardBack());
            elderBillsDto.setHealthAssessment(elder.getHealthAssessment());
            elderBillsDto.setAbilityAssessment(elder.getAbilityAssessment());
            elderBillsDto.setAssessmentReport(elder.getAssessmentReport());
            elderBillsDto.setCareLevelId(elder.getCareLevelId());
            elderBillsDto.setStatus(elder.getStatus());
            elderBillsDto.setBedNo(elder.getBedNo());
            elderBillsDto.setBedId(elder.getBedId());
            elderBillsDto.setCreatedAt(elder.getCreatedAt());
            elderBillsDto.setUpdatedAt(elder.getUpdatedAt());
            elderBillsDto.setCreatedBy(elder.getCreatedBy());
            elderBillsDto.setUpdatedBy(elder.getUpdatedBy());
            elderBillsDto.setExtend1(elder.getExtend1());
            elderBillsDto.setExtend2(elder.getExtend2());
            elderBillsDto.setBills(bills);
            ElderBillsDtos.add(elderBillsDto);
        }
        return ElderBillsDtos;
    }

}
